/*
 *  Emotion Media Center
 *
 *  Copyright (C) 2009 Davide Andreoli <dave@gurumeditation.it>
 *
 *  License LGPL-2.1, see COPYING file at project folder.
 *
 */

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>

#include <Ecore.h>

#include "emc.h"
#include "emc_config.h"
#include "emc_input.h"
#include "emc_module.h"

#include <linux/joystick.h>


#define EMC_MODULE_NAME "input_joy"

#define LOCAL_DEBUG 1
#if LOCAL_DEBUG
#define D DBG
#else
#define D(...)
#endif

static Ecore_Fd_Handler *joy_fd = NULL;
static int joy_oriz_axis = 2;
static int joy_vert_axis = 3;
static int joy_ok_btn = 1;
static int joy_exit_btn = 0;

static int
_joy_event_received(void *data, Ecore_Fd_Handler *fd_handler)
{
   struct js_event js;
   int fd, ret;

   fd = ecore_main_fd_handler_fd_get(fd_handler);

   // read the joystick state
   ret = read(fd, &js, sizeof(struct js_event));
   if (!ret) return 1;

   if (js.value == 0) return 1; //ignore buttons release event

   // emit the correct enna_input
   switch (js.type & ~JS_EVENT_INIT)
   {
      case JS_EVENT_AXIS:
         D("JS_EVENT_AXIS [num %d  val %d]", js.number, js.value);
         if (js.number == joy_vert_axis && js.value > 0) // UP
            emc_input_event_emit(EMC_INPUT_UP);
         else if (js.number == joy_vert_axis && js.value < 0) // DOWN
            emc_input_event_emit(EMC_INPUT_DOWN);
         if (js.number == joy_oriz_axis && js.value > 0) // RIGHT
            emc_input_event_emit(EMC_INPUT_RIGHT);
         else if (js.number == joy_oriz_axis && js.value < 0) // LEFT
            emc_input_event_emit(EMC_INPUT_LEFT);
         break;
         
      case JS_EVENT_BUTTON:
         D("JS_EVENT_BUTTON [num %d  val %d]", js.number, js.value);
         if (js.number == joy_ok_btn) // OK
            emc_input_event_emit(EMC_INPUT_OK);
         else if (js.number == joy_exit_btn) // EXIT
            emc_input_event_emit(EMC_INPUT_EXIT);
         break;

      default:
         break;
   }

   return 1;
}

/* Module interface */

Eina_Bool
module_init(Emc_Module *em)
{
   int fd, num_of_axis = 0, num_of_buttons = 0;
   char name_of_joystick[80];
   const char *joy_device;
   
   // get values from config file
   joy_device = emc_config_string_get("joystick", "device");
   if (!joy_device)
   {
      emc_config_string_set("joystick", "device", "/dev/input/js0");
      joy_device = emc_config_string_get("joystick", "device");
   }
   
   joy_oriz_axis = emc_config_int_get("joystick", "horizontal_axis");
   if (joy_oriz_axis == -1)
   {
      emc_config_int_set("joystick", "horizontal_axis", 2);
      joy_oriz_axis = 2;
   }

   joy_vert_axis = emc_config_int_get("joystick", "vertical_axis");
   if (joy_vert_axis == -1)
   {
      emc_config_int_set("joystick", "vertical_axis", 3);
      joy_vert_axis = 3;
   }

   joy_ok_btn = emc_config_int_get("joystick", "ok_button");
   if (joy_ok_btn == -1)
   {
      emc_config_int_set("joystick", "ok_button", 1);
      joy_ok_btn = 1;
   }

   joy_exit_btn = emc_config_int_get("joystick", "exit_button");
   if (joy_exit_btn == -1)
   {
      emc_config_int_set("joystick", "exit_button", 0);
      joy_exit_btn = 0;
   }

   // open the joystick device
   if((fd = open(joy_device, O_RDONLY)) == -1 )
   {
     ERR("Could not open joystick device: %s", joy_device);
     return EINA_FALSE;
   }

   // get joystick info
   ioctl(fd, JSIOCGAXES, &num_of_axis);
   ioctl(fd, JSIOCGBUTTONS, &num_of_buttons);
   ioctl(fd, JSIOCGNAME(80), &name_of_joystick);
   INF("Found Joystick: %s (axis: %d, buttons: %d device: %s)",
       name_of_joystick, num_of_axis, num_of_buttons, joy_device);

   // ecore fd handler
   joy_fd = ecore_main_fd_handler_add(fd, ECORE_FD_READ, _joy_event_received,
                                      NULL, NULL, NULL);

   return EINA_TRUE;
}

Eina_Bool
module_shutdown(Emc_Module *em)
{
   D(" ");
   if (joy_fd) ecore_main_fd_handler_del(joy_fd);
   return EINA_TRUE;
}

Emc_Module_Api module_api =
{
   EMC_MODULE_API_VERSION,
   EMC_MODULE_NAME,
   "Joystick controls",
   NULL,
   "Module to control enna from the Joystick",
   "bla bla bla<br><b>bla bla bla</b><br><br>bla.",
   {
      module_init,
      module_shutdown
   }
};
